#!/usr/bin/env python

# Copyright 2011 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Street Identity Demo Attribute Provider."""

from google.appengine.dist import use_library
use_library('django', '1.2')
import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
import logging
import cgi

from lib import authn
from lib import http
from lib import utils
from lib.loggable import loggable
from lib.error import handle_error

import model
import app_params as sid_ap_params

__author__ = "Maciej Machulak"
__maintainer__ = "Maciej Machulak"
__email__ = "mmachulak@google.com"

__copyright__ = "Copyright 2011, Google Inc."
__license__ = "Apache License 2.0"
__version__ = "0.1"
__status__ = "Prototype"

      
class AccountHandler(webapp.RequestHandler):
  
    @authn.login_required
    @loggable('account')      
    def get(self): 
        
        user = self.user  
        address_list_empty = user.address_list.get()
                 
        values = {
         'user': user,
         'address_list': user.address_list,
         'address_list_empty': address_list_empty
        }
        path = os.path.join(os.path.dirname(__file__), 'templates/account.html')
        self.response.out.write(template.render(path, values))
       
    @authn.login_required
    @loggable('create address')              
    def post(self):
        
        user = self.user

        address = cgi.escape(self.request.get('address'))
        address_type = cgi.escape(self.request.get('address_type'))
        address_desc = cgi.escape(self.request.get('desc'))
        
        new_address = model.Address(
                              address = address,
                              type = address_type,
                              code = utils.random(),
                              desc = address_desc,
                              user = user)
        new_address.put()
        
        logging.debug('stored new address for the user')
        
        self.redirect('/account')
        
class DelAddressHandler(webapp.RequestHandler):
    
    @authn.login_required     
    @loggable('delete address')      
    def post(self):
        
        address_id = cgi.escape(self.request.get('address_id'))
        logging.debug('preparing to delete address with id %s' % address_id)
        db_address = model.Address.get_by_id(long(address_id))

        if db_address:
          
          logging.debug('address retrieved from the db')
          
          # delete address registration from the IDP
          headers = { http.Header.authorization : http.Header.bearer + ' ' + self.session.access_token }
          url = sid_ap_params.Config.idp
          street_address_api_path = sid_ap_params.Config.address_path
          response = http.delete_request(url, street_address_api_path + str(db_address.key()), headers)
          
          # Delete account locally if deleted at IDP or IDP could not find address
          if response.status != 204 and response.status != 404:
            handle_error(self)
            return
          logging.debug('address successfully disassociated from IDP')
          db_address.delete() 
          logging.debug('address successfully removed from DB')                      
          self.redirect('/account')  
        else:
          
          logging.error('address could not be retrieved from db')
          
          handle_error(self,'Could not delete address','There was a problem with deleting your address.')
          return  
        
class VerifyAddressHandler(webapp.RequestHandler):
    
    @authn.login_required     
    @loggable('verify address')      
    def post(self):
        
        address_id = cgi.escape(self.request.get('address_id'))
        code = cgi.escape(self.request.get('code'))
        
        logging.debug('verifying address %s with code %s' % (address_id,code))
        
        db_address = model.Address.get_by_id(long(address_id))
        if (db_address) and (db_address.code == code):
          
          # TODO: This should be a transaction
          
          logging.debug('found address with the code')
          logging.debug('resetting the code and setting status to verified')
          db_address.code = None
          db_address.verified = True
          db_address.save()
          
          logging.debug('address updated successfully')
          
          # register with the IDP
          headers = { http.Header.authorization : http.Header.bearer + ' ' + self.session.access_token }
          params = {
            'id': str(db_address.key()),
            'desc': db_address.desc,
            'type': db_address.type
          }
          url = sid_ap_params.Config.idp
          street_address_api_path = sid_ap_params.Config.address_path          
          response = http.post_request(url, street_address_api_path, headers, params)
          if response.status != 201:
            # TODO: We should give the user the option to register at a later stage
            logging.error('could not register address with the IDP')
            handle_error(self)
            return
          logging.debug('address registered successfully with the IDP')
          self.redirect('/account') 
        else:          
          handle_error(self,'Invalid code','The code you have submitted is not valid. Are you verifying the correct address?')                      